package com.b511.swpu.cementbackend;

import com.b511.swpu.cementbackend.dto.input.SysCompanyInputDto;
import com.b511.swpu.cementbackend.service.SysCompanyService;
import com.b511.swpu.cementbackend.service.DevService;
import com.b511.swpu.cementbackend.service.MetaDictService;
import com.b511.swpu.cementbackend.dto.input.MetaDictInputDto;
import com.b511.swpu.cementbackend.entity.*;
import com.b511.swpu.cementbackend.repository.*;
import com.b511.swpu.cementbackend.util.Help;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;

@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest
public class InitSystemData {

    @Autowired
    private BoreholeRepository boreholeRepository;

    @Autowired
    private WellBoreStructureRepository wellBoreStructureRepository;

    @Autowired
    private StratumRepository stratumRepository;

    @Autowired
    private PorePressureRepository porePressureRepository;

    @Autowired
    private BurstPressureRepository burstPressureRepository;

    @Autowired
    private MetaDictRepository MetaDictRepository;

    @Autowired
    private MetaDictService metaDictService;

    @Autowired
    private SysUserRepository sysUserRepository;

    @Autowired
    private DevService devService;

    @Autowired
    private MetaSystemUnitRepository metaSystemUnitRepository;

    @Autowired
    private MetaUnitCategoryValueRepository metaUnitCategoryValueRepository;

    @Autowired
    private MetaUnitCategoryRepository metaUnitCategoryRepository;


    @Autowired
    private MetSystemUnitValueRepository metSystemUnitValueRepository;

    @Autowired
    private FormationTemperatureRepository formationTemperatureRepository;

    @Autowired
    private SysMenuRepository sysMenuRepository;

    @Autowired
    private SysRoleRepository sysRoleRepository;

    @Autowired
    private SysCompanyService sysCompanyService;

    @Autowired
    private SysCompanyRepository companyRepository;

    @Autowired
    private SYS_NavigationRepository sys_navigationRepository;

    @Test
    public void init() {
        initSYS_Navigation();
//        devService.initTableAndField();
//        initDataDict();
//        initSysUser();
//        initBorehole();
//        initWellBoreStructure();
//        initStratum();
//        initPorePressure();
//        initBurstPressure();
//        initUnit();
//        initMetaUnitCategory();
//        initMetSystemUnitValue();
//        initFormationTemperature();
//        initMenu();
//        initRole();
//        initCompany();
    }

    private void initDataDict() {
        Map<String,List<String>> companyMap = new HashMap<>();
        companyMap.put("国别",Arrays.asList("中国", "美国"));
        companyMap.put("井别",Arrays.asList("探井", "生产井"));
        companyMap.put("井型",Arrays.asList("生产井","直井"));
        companyMap.put("深度零点",Arrays.asList("转盘面", "其他"));
        Iterator<Map.Entry<String, List<String>>> iterator = companyMap.entrySet().iterator();
        while (iterator.hasNext()){
            String key = iterator.next().getKey();
            metaDictService.addDict(new MetaDictInputDto().setLabel(key));
            metaDictService.addDictChild(MetaDictRepository.findByLabel(key).getCode(),
                    new MetaDictInputDto().setLabel(companyMap.get(key).get(0)));
            metaDictService.addDictChild(MetaDictRepository.findByLabel(key).getCode(),
                    new MetaDictInputDto().setLabel(companyMap.get(key).get(1)));
        }
    }

    private void initSysUser() {
        SysUser sysUser = new SysUser();
        sysUser.setName("xiaojian");
        sysUser.setUsername("xiaojian");
        sysUser.setPassword(Help.encryption("123456"));
        sysUser.setEnable(true);
        sysUser.setMan(false);
        sysUser.setRoles(sysRoleRepository.findAll());
        sysUserRepository.save(sysUser);
    }

    private void initBorehole() {
        List<Borehole> boreholeList = new ArrayList<>();
        for (int i = 0; i < 30; i++) {
            Borehole borehole = new Borehole();
            borehole.setWellName("井" + i)
                    .setWellCategory(U.r() ? "探井" : "生产井")
                    .setWellType(U.r() ? "直井" : "定向井")
                    .setNationality(U.r() ? "中国" : "印度")
                    .setBlock("区块" + i)
                    .setCoordX(U.coordinate())
                    .setCoordY(U.coordinate())
                    .setLongitude(U.coordinate())
                    .setLatitude(U.coordinate())
                    .setStructureLocation(U.coordinate())
                    .setLineLocation(U.coordinate())
                    .setZeroLocation(U.r() ? "转盘面" : "其他")
                    .setTurnPlate(U.f(200))
                    .setWaterDepth(U.f(2000))
                    .setMainObjStratum(U.r() ? "明下段" : "馆上段")
                    .setDrillingPrinciple("完钻原则" + i);
            boreholeList.add(borehole);
        }
        boreholeRepository.saveAll(boreholeList);
    }

    private void initWellBoreStructure() {
        List<Borehole> boreholeList = boreholeRepository.findAll();
        List<WellBoreStructure> wellBoreStructures = new ArrayList<>();
        for (int i = 0; i < 100; i++) {
            WellBoreStructure wellBoreStructure = new WellBoreStructure();
            wellBoreStructure.setBorehole(boreholeList.get(U.i(boreholeList.size())))
                    .setHoleSize(U.f(2000))
                    .setHoleDepth(U.f(20000))
                    .setCasingType(U.r() ? "表层套管" : "技术套管")
                    .setCasingSize(U.f(2000))
                    .setCasingDepth(U.f(20000))
                    .setSteelGrade("钢级" + i)
                    .setBuckleType("扣型" + i)
                    .setCemRtnDepth(U.f(2000))
                    .setHoopDepth(U.f(2000));
            wellBoreStructures.add(wellBoreStructure);
        }
        wellBoreStructureRepository.saveAll(wellBoreStructures);
    }

    private void initStratum() {
        List<Borehole> boreholeList = boreholeRepository.findAll();
        List<Stratum> stratumList = new ArrayList<>();
        for (int i = 0; i < 100; i++) {
            Stratum stratum = new Stratum();
            stratum.setBorehole(boreholeList.get(U.i(boreholeList.size())))
                    .setFormation("组" + i)
                    .setMember("段" + i)
                    .setDepth(U.f(2000))
                    .setThickness(U.f(5000))
                    .setType("岩性" + i)
                    .setSeries("统" + i);
            stratumList.add(stratum);
        }
        stratumRepository.saveAll(stratumList);
    }

    private void initPorePressure() {
        List<Borehole> boreholeList = boreholeRepository.findAll();
        List<PorePressure> porePressureList = new ArrayList<>();
        for (int i = 0; i < 100; i++) {
            PorePressure porePressure = new PorePressure();
            porePressure.setBorehole(boreholeList.get(U.i(boreholeList.size())))
                    .setEquivalentDensity(U.f(5))
                    .setMudDensity(U.f(5))
                    .setTvd(U.f(2000))
                    .setWellDepth(U.f(10000));

            porePressureList.add(porePressure);
        }
        porePressureRepository.saveAll(porePressureList);
    }

    private void initBurstPressure() {
        List<Borehole> boreholeList = boreholeRepository.findAll();
        List<BurstPressure> burstPressureList = new ArrayList<>();
        for (int i = 0; i < 100; i++) {
            BurstPressure burstPressure = new BurstPressure();
            burstPressure.setBorehole(boreholeList.get(U.i(boreholeList.size())))
                    .setEquivalentDensity(U.f(5))
                    .setTvd(U.f(20000))
                    .setWellDepth(U.f(20000));

            burstPressureList.add(burstPressure);
        }
        burstPressureRepository.saveAll(burstPressureList);
    }

    private void initUnit() {
        MetaSystemUnit[] units = new MetaSystemUnit[]{
                new MetaSystemUnit().setName("英制单位"),
                new MetaSystemUnit().setName("国际单位"),
                new MetaSystemUnit().setName("自定义单位")
        };
        metaSystemUnitRepository.saveAll(Arrays.asList(units));
    }

    private void initMetaUnitCategory() {
        MetaUnitCategory[] categories = new MetaUnitCategory[]{
                new MetaUnitCategory().setUnitName("深度/长度").setInternationalUnits("m").setMetaUnitCategoryValues(initMetaUnitCategoryValue()),
                new MetaUnitCategory().setUnitName("直径单位").setInternationalUnits("m").setMetaUnitCategoryValues(initMetaUnitCategoryValue()),
                new MetaUnitCategory().setUnitName("井眼容积").setInternationalUnits("m").setMetaUnitCategoryValues(initMetaUnitCategoryValue())
        };
        metaUnitCategoryRepository.saveAll(Arrays.asList(categories));
    }

    private List<MetaUnitCategoryValue> initMetaUnitCategoryValue() {
        MetaUnitCategoryValue[] values = new MetaUnitCategoryValue[]{
                new MetaUnitCategoryValue().setUnitName("mm"),
                new MetaUnitCategoryValue().setUnitName("cm"),
                new MetaUnitCategoryValue().setUnitName("dm"),
                new MetaUnitCategoryValue().setUnitName("m")};
        return Arrays.asList(values);
    }

    private void initMetSystemUnitValue() {
        List<MetaSystemUnit> systemUnits = metaSystemUnitRepository.findAll();
        List<MetaUnitCategory> unitCategories = metaUnitCategoryRepository.findAll();
        List<MetaSystemUnitValue> values = new ArrayList<>();
        for (MetaSystemUnit metaSystemUnit : systemUnits) {
            for (MetaUnitCategory metaUnitCategory : unitCategories) {
                List<MetaUnitCategoryValue> list = metaUnitCategory.getMetaUnitCategoryValues();
                values.add(new MetaSystemUnitValue()
                        .setMetaSystemUnit(metaSystemUnit)
                        .setMetaUnitCategory(metaUnitCategory)
                        .setMetaUnitCategoryValue(list.get(U.i(list.size()))));
            }
        }
        metSystemUnitValueRepository.saveAll(values);
    }

    @Test
    @Transactional
    public void initFormationTemperature() {
        List<Borehole> boreholeList = boreholeRepository.findAll();
        List<FormationTemperature> formationTemperatureList = new ArrayList<>();
        for (int i = 0; i < 100; i++) {
            FormationTemperature formationTemperature = new FormationTemperature();
            formationTemperature.setBorehole(boreholeList.get(U.i(boreholeList.size())))
                    .setTemperature(U.f(5));
            formationTemperatureList.add(formationTemperature);
        }
        formationTemperatureRepository.saveAll(formationTemperatureList);
    }

    private void initMenu() {
        SysMenu[] menus = new SysMenu[]{
                new SysMenu().setName("管理员").setUrl("/admin").setRouterIndex("1-1-1").setRouterPath("/admin"),
                new SysMenu().setName("井眼概述").setUrl("/borehole").setRouterIndex("1-1-2").setRouterPath("/borehole"),
                new SysMenu().setName("地层破裂压力").setUrl("/burst_pressure").setRouterIndex("1-1-3").setRouterPath("/burst-pressure"),
                new SysMenu().setName("固井总体设计").setUrl("/cementing_construct_data").setRouterIndex("1-1-4").setRouterPath("/cementing-construct-data"),
                new SysMenu().setName("固井现场设计").setUrl("/cementing_site_design").setRouterIndex("1-1-5").setRouterPath("/cementing-site-design"),
                new SysMenu().setName("公司单位").setUrl("/company").setRouterIndex("1-1-6").setRouterPath("/company"),
                new SysMenu().setName("开发者使用").setUrl("/dev").setRouterIndex("1-1-7").setRouterPath("/dev"),
                new SysMenu().setName("地层温度").setUrl("/formation_temperature").setRouterIndex("1-1-8").setRouterPath("/formation-temperature"),
                new SysMenu().setName("数据字典").setUrl("/dict").setRouterIndex("1-1-9").setRouterPath("/dict"),
                new SysMenu().setName("档位转换").setUrl("/category").setRouterIndex("1-2-1").setRouterPath("/category"),
                new SysMenu().setName("地层孔隙压力").setUrl("/pore_pressure").setRouterIndex("1-2-2").setRouterPath("/pore-pressure"),
                new SysMenu().setName("公共接口").setUrl("/public").setRouterIndex("1-2-3").setRouterPath("/public"),
                new SysMenu().setName("地层信息").setUrl("/stratum").setRouterIndex("1-2-4").setRouterPath("/stratum"),
                new SysMenu().setName("角色管理").setUrl("/role").setRouterIndex("1-2-5").setRouterPath("/role"),
                new SysMenu().setName("新增员工").setUrl("/employee").setRouterIndex("1-2-6").setRouterPath("/employee"),
                new SysMenu().setName("员工管理").setUrl("/user").setRouterIndex("1-2-7").setRouterPath("/user"),
                new SysMenu().setName("数据校验").setUrl("/validate").setRouterIndex("1-2-8").setRouterPath("/validate"),
                new SysMenu().setName("井身结构").setUrl("/well_bore_structure").setRouterIndex("1-2-9").setRouterPath("/well-bore-structure")};
        sysMenuRepository.saveAll(Arrays.asList(menus));
    }

    private void initRole() {
        SysRole[] roles = new SysRole[]{
                new SysRole().setName("经理"),
                new SysRole().setName("组长"),
                new SysRole().setName("组员"),
        };
        List<SysMenu> sysMenus = sysMenuRepository.findAll();
        for (SysRole sysRole : roles) {
            sysRole.setSysMenus(sysMenus);
        }
        sysRoleRepository.saveAll(Arrays.asList(roles));
    }

    private void initCompany() {
        String[] level1 = {"西南油气田", "华北油气田"};
        for (String s : level1) {
            sysCompanyService.addSysCompany(new SysCompanyInputDto().setLabel(s));
        }
        String parentCode1 = companyRepository.findByLabel("西南油气田").getCode();
        System.out.println(parentCode1);
        sysCompanyService.addChildSysCompany(parentCode1, new SysCompanyInputDto().setLabel("成都油田"));
        sysCompanyService.addChildSysCompany(parentCode1, new SysCompanyInputDto().setLabel("德阳油田"));
        String parentCode2 = companyRepository.findByLabel("华北油气田").getCode();
        sysCompanyService.addChildSysCompany(parentCode2, new SysCompanyInputDto().setLabel("东北油田"));
        sysCompanyService.addChildSysCompany(parentCode2, new SysCompanyInputDto().setLabel("漠北油田"));
    }

    private void initSYS_Navigation() {
        SYS_Navigation[] navigations = new SYS_Navigation[]{
                new SYS_Navigation().setNAME("数据概览").setCODE("0001").setNO("dashboard").setICON("el-icon-s-marketing"),
                new SYS_Navigation().setNAME("井眼管理").setCODE("0002").setNO("wellManagement").setICON("el-icon-s-home"),
                new SYS_Navigation().setNAME("数据校验").setCODE("0003").setNO("dataValidate").setICON("el-icon-view"),
                new SYS_Navigation().setNAME("数据浏览").setCODE("0004").setNO("data_classification").setICON("el-icon-s-grid"),
                new SYS_Navigation().setNAME("文件浏览").setCODE("0005").setNO("data_documents").setICON("el-icon-folder-opened"),
                new SYS_Navigation().setNAME("数据查询").setCODE("0006").setNO("wellQuery").setICON("el-icon-search"),
                new SYS_Navigation().setNAME("数据分析").setCODE("0007").setNO("data-analyse").setICON("el-icon-s-data"),
                new SYS_Navigation().setNAME("作业量分析").setCODE("000701").setNO("workNumAnalysis").setICON("el-icon-s-data"),
                new SYS_Navigation().setNAME("作业井分析").setCODE("000702").setNO("wellAnalysis").setICON("el-icon-s-data"),
                new SYS_Navigation().setNAME("固井质量分析").setCODE("000703").setNO("qualityAnalysis").setICON("el-icon-s-data"),
                new SYS_Navigation().setNAME("个人中心").setCODE("0008").setNO("person-center").setICON("el-icon-user-solid"),
                new SYS_Navigation().setNAME("我录入的数据").setCODE("000801").setNO("myinput").setICON("el-icon-location"),
                new SYS_Navigation().setNAME("我审核的数据").setCODE("000802").setNO("myvalidate").setICON("el-icon-location"),
                new SYS_Navigation().setNAME("系统管理").setCODE("0009").setNO("data-management").setICON("el-icon-setting"),
                new SYS_Navigation().setNAME("数据字典").setCODE("000901").setNO("data_dict").setICON("el-icon-location"),
                new SYS_Navigation().setNAME("组织机构").setCODE("000902").setNO("Organization").setICON("el-icon-location"),
                new SYS_Navigation().setNAME("用户管理").setCODE("000903").setNO("user_management").setICON("el-icon-location"),
                new SYS_Navigation().setNAME("角色授权").setCODE("000904").setNO("role_authorize").setICON("el-icon-location"),
                new SYS_Navigation().setNAME("角色管理").setCODE("000905").setNO("role_management").setICON("el-icon-location"),
        };
        sys_navigationRepository.saveAll(Arrays.asList(navigations));
    }

    private static class U {

        static boolean r() {
            return Math.random() < 0.5;
        }

        static Double f(int multiple) {
            return f(2, multiple);
        }

        static Double f(int size, int multiple) {
            return new BigDecimal(Math.random() * multiple).setScale(size, BigDecimal.ROUND_HALF_UP).doubleValue();
        }

        static int i(int size) {
            Random random = new Random();
            return random.nextInt(size);
        }

        static String coordinate() {
            return f(150) + "^" + f(150);
        }

        static void swap(int a, int b) {
            int temp = a;
            a = b;
            b = temp;
        }

        ;
    }
}
